<!--
* @Author: your name
* @Date: 2019-12-21 14:24:30
 * @LastEditTime: 2020-08-07 11:17:33
 * @LastEditors: Please set LastEditors
* @Description: In User Settings Edit
* @FilePath: \vue_plugins\src\views\components\Canvas.vue
-->
<template>
  <div class="canvas">
    <van-nav-bar title="云词图" left-arrow fixed :border="false" @click-left="$router.go('-1')" />
    <div class="svg">
      <svg :width="width" :height="height" @mousemove="listener($event)">
        <a :href="tag.href" v-for="(tag,index) in tags" :key="index">
          <text
            :x="tag.x"
            :y="tag.y"
            :font-size="20 * (300/(300-tag.z))"
            :fill-opacity="((100+tag.z)/300)"
            :fill="tag.color"
          >{{tag.text}}</text>
        </a>
      </svg>
    </div>
  </div>
</template>

<script>
export default {
    name: "Canvas",
    data() {
        return {
            width: 300, //svg宽度
            height: 300, //svg高度
            tagsNum: 20, //标签数量
            RADIUS: 150, //球的半径
            speedX: Math.PI / 360, //球一帧绕x轴旋转的角度
            speedY: Math.PI / 360, //球-帧绕y轴旋转的角度
            tags: []
        };
    },
    created() {
        let arr = [
            { text: "html" },
            { text: "css" },
            { text: "javascript" },
            { text: "canvas" },
            { text: "vue" },
            { text: "webpack" },
            { text: "node" },
            { text: "react" },
            { text: "uni-app" },
            { text: "react native" },
            { text: "html" }
        ];
        this.tagsNum = arr.length;
        //初始化标签位置
        let tags = [];
        for (let i = 0; i < this.tagsNum; i++) {
            let tag = {};
            let k = -1 + (2 * (i + 1) - 1) / this.tagsNum;
            let a = Math.acos(k);
            let b = a * Math.sqrt(this.tagsNum * Math.PI); //计算标签相对于球心的角度
            tag.x = this.CX + this.RADIUS * Math.sin(a) * Math.cos(b); //根据标签角度求出标签的x,y,z坐标
            tag.y = this.CY + this.RADIUS * Math.sin(a) * Math.sin(b);
            tag.z = this.RADIUS * Math.cos(a);
            tag.color =
                "#" +
                Math.floor(Math.random() * 0xffffff)
                    .toString(16)
                    .padEnd(6, "0");
            tag.text = arr[i].text;
            tag.href = "https://xiaobai2233.github.io"; //给标签添加链接
            tags.push(tag);
        }
        this.tags = tags; //让vue替我们完成视图更新
    },
    mounted() {
        //使球开始旋转
        setInterval(() => {
            this.rotateX(this.speedX);
            this.rotateY(this.speedY);
        }, 17);
    },
    methods: {
        listener(event) {
            var x = event.clientX - this.CX;
            var y = event.clienty - this.CY;
            this.speedX =
                x * 0.0001 > 0
                    ? Math.min(this.RADIUS * 0.00002, x * 0.0001)
                    : Math.max(-this.RADIUS * 0.00002, x * 0.0001);
            this.speedX =
                y * 0.0001 > 0
                    ? Math.min(this.RADIUS * 0.00002, y * 0.0001)
                    : Math.max(-this.RADIUS * 0.00002, y * 0.0001);
        },
        rotateX(angleX) {
            var cos = Math.cos(angleX);
            var sin = Math.sin(angleX);
            for (let tag of this.tags) {
                var y1 = (tag.y - this.CY) * cos - tag.z * sin + this.CY;
                var z1 = tag.z * cos + (tag.y - this.CY) * sin;
                tag.y = y1;
                tag.z = z1;
            }
        },
        rotateY(angleY) {
            var cos = Math.cos(angleY);
            var sin = Math.sin(angleY);
            for (let tag of this.tags) {
                var x1 = (tag.x - this.CX) * cos - tag.z * sin + this.CX;
                var z1 = tag.z * cos + (tag.x - this.CX) * sin;
                tag.x = x1;
                tag.z = z1;
            }
        }
    },
    computed: {
        CX() {
            //球心x坐标
            return this.width / 2;
        },
        CY() {
            //球心y坐标
            return this.height / 2;
        }
    }
};
</script>

<style lang="less" scoped>
.canvas {
    padding-top: 60px;
    .svg {
        margin: 0px auto;
        box-shadow: 0 0 10px 0 rgba(0, 0, 0, 0.3);
        border-radius: 50%;
        overflow: hidden;
        width: 300px;
        height: 300px;
    }
}
</style>